package dnl.net.netclip;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.util.SessionLog;

import dnl.logging.LightLog;

public class NetClipProtocolHandler extends IoHandlerAdapter {


	public NetClipProtocolHandler() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.mina.common.IoHandlerAdapter#exceptionCaught(org.apache.mina.common.IoSession,
	 *      java.lang.Throwable)
	 */
	@Override
	public void exceptionCaught(IoSession session, Throwable cause) {
		SessionLog.error(session, "", cause);
		// Close connection when unexpected exception is caught.
		session.close();
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.mina.common.IoHandlerAdapter#messageReceived(org.apache.mina.common.IoSession,
	 *      java.lang.Object)
	 */
	@Override
	public void messageReceived(IoSession session, Object message) {
		String theMessage = (String) message;
		ClipCommand accessCommand = ClipCommand.valueOf(theMessage);
		LightLog.info("recevied message: " + message);
		switch (accessCommand) {
		case GET_CLIP:
			Object clipboardContent = getClipboardContents();
			SocketAddress remoteAddress = session.getRemoteAddress();
			if (remoteAddress instanceof InetSocketAddress) {
				InetSocketAddress inetAddress = (InetSocketAddress) remoteAddress;
				LightLog.info("Sending clipboard to: "
						+ inetAddress.getHostName() + ", content type="
						+ clipboardContent.getClass().getName());
			} else {
				LightLog.info("Sending clipboard to: " + remoteAddress
						+ ", content type="
						+ clipboardContent.getClass().getName());
			}
			session.write(clipboardContent);
			break;
		}
	}

	@SuppressWarnings("unchecked")
	public Object getClipboardContents() {
		String result = "";
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		// odd: the Object param of getContents is not currently used
		Transferable contents = clipboard.getContents(null);

		if (contents == null) {
			return result;
		}

		if (contents.isDataFlavorSupported(DataFlavor.imageFlavor)) {
			try {
				Image image = (Image) contents
						.getTransferData(DataFlavor.imageFlavor);
				return ImageContent.fromImage(image);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (contents
				.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
			try {
				java.util.List<File> files = (java.util.List<File>) contents
						.getTransferData(DataFlavor.javaFileListFlavor);
				return FileContent.fromFile(files.get(0));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
			try {
				result = (String) contents
						.getTransferData(DataFlavor.stringFlavor);
			} catch (UnsupportedFlavorException ex) {
				ex.printStackTrace();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}

		return result;
	}
}
